home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / jpegsrc4.zip / JRDPPM.C < prev    next >
C/C++ Source or Header  |  1992-12-02  |  14KB  |  460 lines

  1. /*
  2.  * jrdppm.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to read input images in PPM format.
  9.  * The PBMPLUS library is NOT required to compile this software,
  10.  * but it is highly useful as a set of PPM image manipulation programs.
  11.  *
  12.  * These routines may need modification for non-Unix environments or
  13.  * specialized applications.  As they stand, they assume input from
  14.  * an ordinary stdio stream.  They further assume that reading begins
  15.  * at the start of the file; input_init may need work if the
  16.  * user interface has already read some data (e.g., to determine that
  17.  * the file is indeed PPM format).
  18.  *
  19.  * These routines are invoked via the methods get_input_row
  20.  * and input_init/term.
  21.  */
  22.  
  23. #include "jinclude.h"
  24.  
  25. #ifdef PPM_SUPPORTED
  26.  
  27.  
  28. /* Portions of this code are based on the PBMPLUS library, which is:
  29. **
  30. ** Copyright (C) 1988 by Jef Poskanzer.
  31. **
  32. ** Permission to use, copy, modify, and distribute this software and its
  33. ** documentation for any purpose and without fee is hereby granted, provided
  34. ** that the above copyright notice appear in all copies and that both that
  35. ** copyright notice and this permission notice appear in supporting
  36. ** documentation.  This software is provided "as is" without express or
  37. ** implied warranty.
  38. */
  39.  
  40.  
  41. /* Macros to deal with unsigned chars as efficiently as compiler allows */
  42.  
  43. #ifdef HAVE_UNSIGNED_CHAR
  44. typedef unsigned char U_CHAR;
  45. #define UCH(x)    ((int) (x))
  46. #else /* !HAVE_UNSIGNED_CHAR */
  47. #ifdef CHAR_IS_UNSIGNED
  48. typedef char U_CHAR;
  49. #define UCH(x)    ((int) (x))
  50. #else
  51. typedef char U_CHAR;
  52. #define UCH(x)    ((int) (x) & 0xFF)
  53. #endif
  54. #endif /* HAVE_UNSIGNED_CHAR */
  55.  
  56.  
  57. #define    ReadOK(file,buffer,len)    (JFREAD(file,buffer,len) == ((size_t) (len)))
  58.  
  59.  
  60. /*
  61.  * On most systems, reading individual bytes with getc() is drastically less
  62.  * efficient than buffering a row at a time with fread().  But we must
  63.  * allocate the row buffer in near data space on PCs, because we are assuming
  64.  * small-data memory model, wherein fread() can't reach far memory.  If you
  65.  * need to process very wide images on a PC, you may have to use the getc()
  66.  * approach.  In that case, define USE_GETC_INPUT.
  67.  */
  68.  
  69. #ifndef USE_GETC_INPUT
  70. static U_CHAR * row_buffer;    /* holds 1 pixel row's worth of raw input */
  71. #endif
  72.  
  73. static JSAMPLE * rescale;    /* => maxval-remapping array, or NULL */
  74.  
  75.  
  76. LOCAL int
  77. pbm_getc (FILE * file)
  78. /* Read next char, skipping over any comments */
  79. /* A comment/newline sequence is returned as a newline */
  80. {
  81.   register int ch;
  82.   
  83.   ch = getc(file);
  84.   if (ch == '#') {
  85.     do {
  86.       ch = getc(file);
  87.     } while (ch != '\n' && ch != EOF);
  88.   }
  89.   return ch;
  90. }
  91.  
  92.  
  93. LOCAL unsigned int
  94. read_pbm_integer (compress_info_ptr cinfo)
  95. /* Read an unsigned decimal integer from the PPM file */
  96. /* Swallows one trailing character after the integer */
  97. /* Note that on a 16-bit-int machine, only values up to 64k can be read. */
  98. /* This should not be a problem in practice. */
  99. {
  100.   register int ch;
  101.   register unsigned int val;
  102.   
  103.   /* Skip any leading whitespace */
  104.   do {
  105.     ch = pbm_getc(cinfo->input_file);
  106.     if (ch == EOF)
  107.       ERREXIT(cinfo->emethods, "Premature EOF in PPM file");
  108.   } while (ch == ' ' || ch == '\t' || ch == '\n');
  109.   
  110.   if (ch < '0' || ch > '9')
  111.     ERREXIT(cinfo->emethods, "Bogus data in PPM file");
  112.   
  113.   val = ch - '0';
  114.   while ((ch = pbm_getc(cinfo->input_file)) >= '0' && ch <= '9') {
  115.     val *= 10;
  116.     val += ch - '0';
  117.   }
  118.   return val;
  119. }
  120.  
  121.  
  122. /*
  123.  * Read one row of pixels.
  124.  *
  125.  * We provide several different versions depending on input file format.
  126.  * In all cases, input is scaled to the size of JSAMPLE; it's possible that
  127.  * when JSAMPLE is 12 bits, this would not really be desirable.
  128.  *
  129.  * Note that a really fast path is provided for reading raw files with
  130.  * maxval = MAXJSAMPLE, which is the normal case (at least for 8-bit JSAMPLEs).
  131.  */
  132.  
  133.  
  134. METHODDEF void
  135. get_text_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  136. /* This version is for reading text-format PGM files with any maxval */
  137. {
  138.   register JSAMPROW ptr0;
  139.   register unsigned int val;
  140.   register long col;
  141.   
  142.   ptr0 = pixel_row[0];
  143.   for (col = cinfo->image_width; col > 0; col--) {
  144.     val = read_pbm_integer(cinfo);
  145.     if (rescale != NULL)
  146.       val = rescale[val];
  147.     *ptr0++ = (JSAMPLE) val;
  148.   }
  149. }
  150.  
  151.  
  152. METHODDEF void
  153. get_text_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  154. /* This version is for reading text-format PPM files with any maxval */
  155. {
  156.   register JSAMPROW ptr0, ptr1, ptr2;
  157.   register unsigned int val;
  158.   register long col;
  159.   
  160.   ptr0 = pixel_row[0];
  161.   ptr1 = pixel_row[1];
  162.   ptr2 = pixel_row[2];
  163.   for (col = cinfo->image_width; col > 0; col--) {
  164.     val = read_pbm_integer(cinfo);
  165.     if (rescale != NULL)
  166.       val = rescale[val];
  167.     *ptr0++ = (JSAMPLE) val;
  168.     val = read_pbm_integer(cinfo);
  169.     if (rescale != NULL)
  170.       val = rescale[val];
  171.     *ptr1++ = (JSAMPLE) val;
  172.     val = read_pbm_integer(cinfo);
  173.     if (rescale != NULL)
  174.       val = rescale[val];
  175.     *ptr2++ = (JSAMPLE) val;
  176.   }
  177. }
  178.  
  179.  
  180. #ifdef USE_GETC_INPUT
  181.  
  182.  
  183. METHODDEF void
  184. get_scaled_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  185. /* This version is for reading raw-format PGM files with any maxval */
  186. {
  187.   register FILE * infile = cinfo->input_file;
  188.   register JSAMPROW ptr0;
  189.   register long col;
  190.   
  191.   ptr0 = pixel_row[0];
  192.   for (col = cinfo->image_width; col > 0; col--) {
  193.     *ptr0++ = rescale[getc(infile)];
  194.   }
  195. }
  196.  
  197.  
  198. METHODDEF void
  199. get_scaled_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  200. /* This version is for reading raw-format PPM files with any maxval */
  201. {
  202.   register FILE * infile = cinfo->input_file;
  203.   register JSAMPROW ptr0, ptr1, ptr2;
  204.   register long col;
  205.   
  206.   ptr0 = pixel_row[0];
  207.   ptr1 = pixel_row[1];
  208.   ptr2 = pixel_row[2];
  209.   for (col = cinfo->image_width; col > 0; col--) {
  210.     *ptr0++ = rescale[getc(infile)];
  211.     *ptr1++ = rescale[getc(infile)];
  212.     *ptr2++ = rescale[getc(infile)];
  213.   }
  214. }
  215.  
  216.  
  217. METHODDEF void
  218. get_raw_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  219. /* This version is for reading raw-format PGM files with maxval = MAXJSAMPLE */
  220. {
  221.   register FILE * infile = cinfo->input_file;
  222.   register JSAMPROW ptr0;
  223.   register long col;
  224.   
  225.   ptr0 = pixel_row[0];
  226.   for (col = cinfo->image_width; col > 0; col--) {
  227.     *ptr0++ = (JSAMPLE) getc(infile);
  228.   }
  229. }
  230.  
  231.  
  232. METHODDEF void
  233. get_raw_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  234. /* This version is for reading raw-format PPM files with maxval = MAXJSAMPLE */
  235. {
  236.   register FILE * infile = cinfo->input_file;
  237.   register JSAMPROW ptr0, ptr1, ptr2;
  238.   register long col;
  239.   
  240.   ptr0 = pixel_row[0];
  241.   ptr1 = pixel_row[1];
  242.   ptr2 = pixel_row[2];
  243.   for (col = cinfo->image_width; col > 0; col--) {
  244.     *ptr0++ = (JSAMPLE) getc(infile);
  245.     *ptr1++ = (JSAMPLE) getc(infile);
  246.     *ptr2++ = (JSAMPLE) getc(infile);
  247.   }
  248. }
  249.  
  250.  
  251. #else /* use row buffering */
  252.  
  253.  
  254. METHODDEF void
  255. get_scaled_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  256. /* This version is for reading raw-format PGM files with any maxval */
  257. {
  258.   register JSAMPROW ptr0;
  259.   register U_CHAR * row_bufferptr;
  260.   register long col;
  261.   
  262.   if (! ReadOK(cinfo->input_file, row_buffer, cinfo->image_width))
  263.     ERREXIT(cinfo->emethods, "Premature EOF in PPM file");
  264.   ptr0 = pixel_row[0];
  265.   row_bufferptr = row_buffer;
  266.   for (col = cinfo->image_width; col > 0; col--) {
  267.     *ptr0++ = rescale[UCH(*row_bufferptr++)];
  268.   }
  269. }
  270.  
  271.  
  272. METHODDEF void
  273. get_scaled_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  274. /* This version is for reading raw-format PPM files with any maxval */
  275. {
  276.   register JSAMPROW ptr0, ptr1, ptr2;
  277.   register U_CHAR * row_bufferptr;
  278.   register long col;
  279.   
  280.   if (! ReadOK(cinfo->input_file, row_buffer, 3 * cinfo->image_width))
  281.     ERREXIT(cinfo->emethods, "Premature EOF in PPM file");
  282.   ptr0 = pixel_row[0];
  283.   ptr1 = pixel_row[1];
  284.   ptr2